<script lang="ts">
import {defineComponent, ref, getCurrentInstance, onMounted, ComponentInternalInstance, defineAsyncComponent} from "vue"
import request from "@/units/request"
import formCreate from '@form-create/element-ui'
import {CloneData} from "@/units/tool";
import {FormOptionDefault} from "@/components/DynamicForm/config";
import {useCloseMessageBox, useSuccessDialog} from "@/hooks/DialogMsg"
import {CreatedUrl} from "@/units/uri";
import {Ref, UnwrapRef} from "@vue/reactivity";
import {HttpResultData} from "@/types/project";

export default defineComponent({
  name: "FormComponent",
  emits: {
    change: (field: string, value: any, rule: any[], fApi: object, setFlag: boolean) => true,
    reload: (instance: ComponentInternalInstance) => true,
    close: (value: any) => true,
    success: (value: any) => true,
    config: (value: any) => true
  },
  props: {
    popup: {//是否是弹窗模式
      type: Boolean,
      default: false
    },
    successTips: {
      type: Boolean,
      default: true
    },
    api: {//接口地址
      type: String,
      required: true
    },
    query: {//请求参数
      type: Object,
      default() {
        return {}
      }
    },
  },
  components: {
    AppFormCreate: formCreate.$form()
  },
  created() {
    formCreate.component('image-input', defineAsyncComponent((): any => import("@/components/Form/ImageInput.vue")))
    formCreate.component('image-list-input', defineAsyncComponent((): any => import("@/components/Form/ImageListInput.vue")))
    formCreate.component('tags-input', defineAsyncComponent((): any => import("@/components/Form/TagsInput.vue")))
    formCreate.component('editor', defineAsyncComponent((): any => import("@/components/Form/Editor/Index.vue")))
    formCreate.component('ico-choice', defineAsyncComponent((): any => import("@/components/Form/IcoChoice.vue")))
  },
  setup(props, {emit, expose}) {
    /**
     * 关闭页面-区分弹窗和页面
     */
    const close = props.popup ? useCloseMessageBox() : function () {
      emit('close', getValue())
    }

    const loading = ref(false)
    const forminit = ref(true)

    const action: Ref<UnwrapRef<string>> = ref('')//请求地址
    const method: Ref<UnwrapRef<string>> = ref('POST')//请求方法
    const rule: Ref<UnwrapRef<any[]>> = ref([])//表单规则
    const option: Ref<UnwrapRef<any>> = ref({})//表单配置
    const title: Ref<UnwrapRef<string>> = ref('')//表单规则
    const formData: Ref<UnwrapRef<any>> = ref({})//表单数据
    request(props.api, props.query).then((res: HttpResultData<any>) => {
      if (res.code === 200) {
        action.value = res.data.action
        method.value = res.data.method
        let rules=[...res.data.rule]
        if (!props.popup) {
          rules.reverse()
        }
        rule.value=rules
        option.value = CloneData({...FormOptionDefault(), ...res.data.option})
        title.value = res.data.title
        emit('config', res.data)
      }else{
        emit('close', res.data)
      }
      forminit.value = false
    })

    /**
     * 表单数据变化事件
     */
    function formChange(field: string, value: any, rule: any, fApi: any, setFlag: boolean) {
      if (value === null && rule.type === 'cascader') {
        fApi.setValue(field, [])//傻逼组件，默认值为array,选中值为array，清空就尼玛成了null
      }
      emit('change', field, value, rule, fApi, setFlag)
    }


    /**
     * 获取动态表单值
     */
    function getValue(): { [key: string]: any } {
      let values: { [key: string]: any } = CloneData(formData.value.formData())
      for (let key in values) {
        if (values[key] === null || values[key] === undefined) {
          let rule = formData.value.getRule(key)
          if (rule.type === 'select') {
            values[key] = ''
          }
        }
      }
      return values
    }


    /**
     * 提交表单值
     */
    function submitData() {
      if (loading.value === true) return false
      loading.value = true
      const api = action.value ? action.value : CreatedUrl(props.api, props.query)
      const FormData: any = getValue()
      request(api, FormData, method.value).then((res: HttpResultData<any>) => {
        if (res.code === 200) {
          if (props.successTips) {
            useSuccessDialog(res.msg).then(() => {
              emit('close', {...FormData})
              emit('success', {...FormData})
              close()
            })
          } else {
            emit('close', {...FormData})
            emit('success', {...FormData})
            close()
          }
          setTimeout(() => loading.value = false, 500)
        } else {
          loading.value = false
        }
      })
    }


    /**
     * 重置表单值
     */
    function resetValue() {
      formData.value.resetFields()
    }

    //对外导出方法实例
    expose({getValue, submitData, resetValue})


    //加载完毕返回页面示例
    onMounted(() => {
      //@ts-ignore
      emit('reload', getCurrentInstance())
    })

    return {
      action, method, rule, option, title, formData, formChange, forminit
    }
  }
})
</script>

<template>
  <div class="app-form-create">
    <el-page-header>
      <template #content>
        <span class="text-large font-600 mr-3">{{ title }} </span>
      </template>
    </el-page-header>
    <div class="app-margin-top-large">
      <div v-if="forminit" style="height: 300px;" v-loading="true" element-loading-text="玩命加载中......"></div>
      <div v-else>
        <app-form-create :option="option" @change="formChange" v-model:api="formData" :rule="rule"></app-form-create>
      </div>
    </div>
  </div>
</template>